home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / REALITY / atom / geom.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  25.9 KB  |  1,305 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /* geom.c
  18.  * ------
  19.  *
  20.  * $Revision: 1.24 $
  21.  *
  22.  */
  23.  
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <math.h>
  27. #include <gl/gl.h>
  28. #include <gl/device.h>
  29. #include <sys/types.h>
  30. #include <sys/times.h>
  31. #include <sys/param.h>
  32. #include <fmclient.h>
  33. #include <gl/sphere.h>
  34.  
  35. #include "mview.h"
  36. #include "geom.h"
  37. #include "light.h"
  38.  
  39. #define ABS(x) (((x) > 0) ? (x) : (0 - (x)))
  40.  
  41.  
  42. #define DIST 80.0
  43. #define ANGLE_SHOCK_ABSORBER 0.4
  44. #define COORD_SHOCK_ABSORBER 0.04
  45. #define AUTO_ROT_TOL 5
  46.  
  47. /*
  48.  * stereo defines - for units in inches
  49.  */
  50.  
  51. #define PIXELS    50.0        /* pixels per inch in stereo mode */
  52. #define SCREEN_WIDTH  15.       /* width of screen in inches*/
  53. #define SCREEN_HEIGHT 10.625    /* height of screen in inches*/
  54. #define DISTANCE_TO_SCREEN 30.  /* distance from eye to screen (nearclip)*/
  55.  
  56. #define CLIP_FACTOR (1./8.00) /* to move near clip in */
  57.  
  58. #define NEAR_CLIP_DISTANCE    (DISTANCE_TO_SCREEN*CLIP_FACTOR)
  59. #define FAR_CLIP_DISTANCE    (DISTANCE_TO_SCREEN*500.)  
  60.  
  61. #define DESIRED_SIZE_ON_SCREEN    2.
  62. #define WORLD_SPACE_SIZE    2.
  63.  
  64. #define IOD 2.3            /* eye offset distance */
  65.  
  66. static float viewOffset = IOD;
  67. static float projOffset = 0.;
  68.  
  69. /****************************************************************************/
  70.  
  71. static float centerx=0.0, centery=0.0, centerz=0.0;
  72. static int AtomsInitialized = 0;
  73. static int BondsInitialized = 0;
  74. static int ModelRead = 0;
  75. static atom_t *Atoms = 0;
  76. static bond_t *Bonds = 0;
  77.  
  78. static int LightModel;
  79. static unsigned AAmode = SML_OFF;
  80.  
  81. long FogType = FG_PIX_LIN;
  82. static float fogprops[5] = {1.0,40.0,0.0,0.0,0.0};
  83.  
  84. /* 
  85.  * atom types
  86.  */
  87. #define AT_CARBON    1
  88. #define AT_HYDROGEN    2
  89. #define AT_OXYGEN    3
  90. #define AT_NITROGEN    4
  91. #define AT_SULFER    5
  92. #define AT_Z        6
  93. #define AT_U        7
  94. #define AT_OTHER    8
  95.  
  96. /* ambient/diffuse color data */
  97. float atom_colors[][4] = {
  98. /* AT_CARBON - grey */   {0.15, 0.15, 0.15, 1.0}, 
  99. /* AT_HYDROGEN - white */  {0.55, 0.55, 0.55, 1.0}, 
  100. /* AT_OXYGEN - red */    {0.5, 0.0, 0.0, 1.0}, 
  101. /* AT_NITROGEN - blue */   {0.12, 0.12, 0.35, 1.0},
  102. /* AT_SULFER - yellow */ {0.5, 0.5, 0.0, 1.0},
  103. /* AT_Z - green */ {0.0, 0.5, 0.0, 1.0},
  104. /* AT_U  - cyan */ {0.0, 0.5, 0.5, 1.0},
  105. /* AT_OTHER - pink */   {120.0/255.0, 0.0, 50.0/255.0, 1.0} ,
  106. };
  107.  
  108. float *atom_props[] = 
  109. {
  110. /* AT_CARBON - grey */  MatGreyprops, 
  111. /* AT_HYDROGEN - white */  MatWhiteprops, 
  112. /* AT_OXYGEN - red */    MatRedprops, 
  113. /* AT_NITROGEN - blue */   MatBlueprops,
  114. /* AT_SULFER - yellow */ MatYellowprops,
  115. /* AT_Z - green */   MatGreenprops, 
  116. /* AT_U - cyan */   MatCyanprops, 
  117. /* AT_OTHER - pink */   MatPinkprops, 
  118. };
  119.  
  120. float FOVY = 400.;
  121. float Left = -24.0, Right = 24.0, Bottom = -20.0, Top = 20.0;
  122. float CenterZ = -DISTANCE_TO_SCREEN;
  123. float Near = NEAR_CLIP_DISTANCE, Far = FAR_CLIP_DISTANCE;
  124. long ZMin, ZMax;
  125.  
  126. static KERNEL Kernel = {
  127.     18,
  128.     {{0.439362, 0.198547, 0.},
  129.     {0.209265, 0.518289, 0.},
  130.     {0.810847, 0.489433, 0.},
  131.     {0.818721, 0.089856, 0.},
  132.     {0.170028, 0.911008, 0.},
  133.     {0.551777, 0.792868, 0.},
  134.     {0.339362, 0.198547, 0.},
  135.     {0.509265, 0.518289, 0.},
  136.     {0.710847, 0.489433, 0.},
  137.     {0.918721, 0.089856, 0.},
  138.     {0.070028, 0.911008, 0.},
  139.     {0.251777, 0.592868, 0.},
  140.     {0.439362, 0.198547, 0.},
  141.     {0.609265, 0.318289, 0.},
  142.     {0.710847, 0.589433, 0.},
  143.     {0.918721, 0.189856, 0.},
  144.     {0.170028, 0.911008, 0.},
  145.     {0.351777, 0.792868, 0.}}
  146. };
  147.  
  148. #define SPH_KERNAL_SIZE 18
  149. static float Zkernel[SPH_KERNAL_SIZE] = {
  150.     9., 26., 30., 44., 51., 66., 
  151.     11., 15., 33., 66., 91., 101., 
  152.     3., 13., 18., 37., 86., 95.
  153. };
  154.  
  155. static float Xkernel[SPH_KERNAL_SIZE] = {
  156.     -3., 3., -1., 1., -5., 5., 
  157.     -2., 2., -4., 4., -1.5, 1.5, 
  158.     -3.5, 3.5, -2.5, 2.5, -4.5, 4.5
  159. };
  160.             
  161. static Matrix 
  162.     IdentityMat = {
  163.     1.0, 0.0, 0.0, 0.0,
  164.     0.0, 1.0, 0.0, 0.0,
  165.     0.0, 0.0, 1.0, 0.0,
  166.     0.0, 0.0, 0.0, 1.0
  167.     }, 
  168.     Mat = {
  169.     1.0, 0.0, 0.0, 0.0, 
  170.     0.0, 1.0, 0.0, 0.0, 
  171.     0.0, 0.0, 1.0, 0.0, 
  172.     0.0, 0.0, 0.0, 1.0, 
  173.     };
  174.  
  175. static float Mx, My;
  176. static long Xpos, Ypos;
  177. static long NewXpos, NewYpos;
  178. static float TransX = 0.0f, TransY = 0.0f, TransZ = 0.0f;
  179. static float ScaleFactor = 1.0f;
  180.  
  181. static int NumPolysAtom;
  182. static int NumPolys;
  183.  
  184. long Menu = -1;
  185. int
  186.     GeomLeftDown = 0, 
  187.     GeomRightDown = 0, 
  188.     GeomMiddleDown = 0;
  189. int RotMode = 0;
  190.  
  191. long GeomWid = -1;
  192. long GeomXorigin = 0, GeomYorigin = 0;
  193. long GeomXsize = 1280, GeomYsize = 1024; 
  194. float GeomAspect = 1280./1024.;
  195. float GeomXInches;
  196.  
  197. atomtab_t AtomTab[8];
  198. bondtab_t BondTab[8];
  199. int Natoms = 0, Nbonds = 0;
  200.  
  201. int Alreadyaccumulated = 0;
  202.  
  203. extern fmfonthandle FontScreen, FontScreen8;
  204. extern fmfontinfo FontScreenInfo, FontScreen8Info;
  205.  
  206. /****************************************************************************/
  207.  
  208. static void PrintMat(Matrix mat);
  209. static void ConfigureWindow(void);
  210. static float** SphRotMatrix(float rx, float ry, float rz);
  211. static void InitAtoms(void);
  212. static void InitBonds(void);
  213. static void SetupAtomTab(int natoms, atom_t *atoms);
  214. static void SetupBondTab(int nbonds, bond_t *bonds);
  215. static void ClearScreen(void);
  216. static void ResetLight(void);
  217. static void DrawAtoms(void);
  218. static void DrawBonds(void);
  219. static void TranslateXY(void);
  220. static void Scale(void);
  221. static void RotateXY(int flag);
  222. static void Zoom(void);
  223. static void SetMatter(int m);
  224. static void AccWindow(float pixdx, float pixdy, float eyedx, float eyedy, 
  225.             float focus);
  226. static void ResetMat(Matrix m);
  227. static void TessDown(void);
  228. static void TessUp(void);
  229. static void DrawInfo(void);
  230. static void DrawScene(void);
  231. static void stereopersp(int fovy, float aspect,
  232.         float near, float far, float conv, float eye);
  233.  
  234. /****************************************************************************/
  235.  
  236. void InitData()
  237. {
  238.     bzero((char *)AtomTab, sizeof(AtomTab));
  239.     bzero((char *)BondTab, sizeof(BondTab));
  240.     AtomsInitialized = 0;
  241.     if (Atoms) free(Atoms);
  242.     InitAtoms();
  243.     BondsInitialized = 0;
  244.     if (Bonds) free(Bonds);
  245.     InitBonds();
  246.     ModelRead = 1;
  247. }
  248.  
  249. static void InitAtoms()
  250. {
  251.     if (!AtomsInitialized) {
  252.     Natoms = readatoms(Models[ModelId].atom, &Atoms, 
  253.         ¢erx, ¢ery, ¢erz);
  254.     SetupAtomTab(Natoms, Atoms);
  255.     AtomsInitialized = 1;
  256.     }
  257. }
  258.  
  259. static void InitBonds()
  260. {
  261.     if (!BondsInitialized) {
  262.     Nbonds = readbonds(Models[ModelId].bond, &Bonds, 
  263.         ¢erx, ¢ery, ¢erz);
  264.     SetupBondTab(Nbonds, Bonds);
  265.     BondsInitialized = 1;
  266.     }
  267. }
  268.  
  269. static void SetupAtomTab(int natoms, atom_t *atoms)
  270. {
  271.     int i;
  272.     atom_t *tptr[8];
  273.     atom_t *aptr;
  274.  
  275.     /* malloc AtomTab */
  276.     for (i = 0; i < 8; i++) {
  277.     if (AtomTab[i].natoms > 0) {
  278.            AtomTab[i].atomlist = (atom_t *)
  279.                  malloc (AtomTab[i].natoms * sizeof(atom_t));
  280.        AtomTab[i].atomcol = i;
  281.     }
  282.     }
  283.     for (i=0; i < 8; i++) {
  284.     tptr[i] =  AtomTab[i].atomlist;
  285.     }
  286.     /* put atoms in  AtomTab */
  287.     aptr = atoms;
  288.     for (i = 0; i < natoms; i++) {
  289.     tptr[aptr->id]->org_rad  = aptr->org_rad;
  290.     tptr[aptr->id]->rad  = aptr->rad;
  291.         tptr[aptr->id]->id  = aptr->id;
  292.         tptr[aptr->id]->x  = aptr->x;
  293.         tptr[aptr->id]->y  = aptr->y;
  294.         tptr[aptr->id]->z  = aptr->z;
  295.         tptr[aptr->id]->r  = aptr->r;
  296.         tptr[aptr->id]->g  = aptr->g;
  297.         tptr[aptr->id]->b  = aptr->b;
  298.     tptr[aptr->id] += 1;
  299.     aptr++;
  300.     }
  301. }
  302.  
  303. static void SetupBondTab(int nbonds, bond_t *bonds)
  304. {
  305.     int i;
  306.     bond_t *tptr[8];
  307.     bond_t *bptr;
  308.  
  309.     /* malloc BondTab */
  310.     for (i = 0; i < 8; i++) {
  311.     if (BondTab[i].nbonds > 0) {
  312.            BondTab[i].bondlist = (bond_t *)
  313.                  malloc (BondTab[i].nbonds * sizeof(bond_t));
  314.     }
  315.     }
  316.     for (i=0; i < 8; i++) {
  317.     tptr[i] =  BondTab[i].bondlist;
  318.     }
  319.     /* put bonds in  BondTab */
  320.     bptr = bonds;
  321.     for (i = 0; i < nbonds; i++) {
  322.     tptr[bptr->id]->id  = bptr->id;
  323.         tptr[bptr->id]->sx  = bptr->sx;
  324.         tptr[bptr->id]->sy  = bptr->sy;
  325.         tptr[bptr->id]->sz  = bptr->sz;
  326.         tptr[bptr->id]->ex  = bptr->ex;
  327.         tptr[bptr->id]->ey  = bptr->ey;
  328.         tptr[bptr->id]->ez  = bptr->ez;
  329.         tptr[bptr->id]->r  = bptr->r;
  330.         tptr[bptr->id]->g  = bptr->g;
  331.         tptr[bptr->id]->b  = bptr->b;
  332.     tptr[bptr->id] += 1;
  333.     bptr++;
  334.     }
  335. }
  336.  
  337. static void ConfigureWindow(void)
  338. {
  339.     getorigin(&GeomXorigin, &GeomYorigin);
  340.     getsize(&GeomXsize, &GeomYsize);
  341.     GeomAspect = ((float)GeomXsize / (float)GeomYsize);
  342.     Top = Right / GeomAspect;
  343.     Bottom = -Top;
  344.     GeomXInches = ((float)GeomXsize/PIXELS);
  345. }
  346.  
  347. void OpenGeomWindow()
  348. {
  349.     if (UsePrefsize) prefsize(GeomXsize, GeomYsize);
  350.     else if (UsePrefposition)
  351.     prefposition(GeomXorigin, GeomXorigin + GeomXsize - 1, 
  352.         GeomYorigin, GeomYorigin + GeomYsize - 1);
  353.     else keepaspect(5,4);
  354.     if (Debug)
  355.     foreground();
  356.     GeomWid = winopen(ProgName);
  357.     SetGeomTitle();
  358.     if (GeomWid == -1) {
  359.     fprintf(stderr, "%s: no additional graphics windows are available\n", 
  360.         ProgName);
  361.     DoExit(-1);
  362.     }
  363.  
  364.     RGBmode();
  365.         doublebuffer();
  366.     DoMultisample();
  367.     gconfig();
  368.     ConfigureWindow();
  369.     zbuffer(1);
  370.     ClearScreen();
  371.     swapbuffers();
  372.     clear();
  373.     subpixel(1);
  374.     lsetdepth(0, ZMax);
  375.  
  376.     fogvertex(FogType, fogprops);
  377. }
  378.  
  379. static void ClearScreen()
  380. {
  381.     /*cpack(BackgroundColor);*/
  382.     /*clear(); zclear();*/
  383.     czclear(BackgroundColor, ZMax);
  384. }
  385.  
  386. void InitSphere()
  387. {
  388.     sphmode(SPH_DEPTH, SphereDepth);
  389.     sphmode(SPH_TESS, SphereType);
  390.     sphmode(SPH_PRIM, SpherePrim);
  391.     if (!RollMode)
  392.     {
  393.     if (Hemi)
  394.         sphmode(SPH_HEMI, Hemi);
  395.     else
  396.         SetBackface(1);
  397.     }
  398.     sphmode(SPH_ORIENT, Orient);
  399. }
  400.  
  401.  
  402. void InitAccBuf(void)
  403. {
  404.     static int initialized = 0;
  405.  
  406.     winset(GeomWid);
  407.     if (!initialized) {
  408.     if (!HwAccBuf()) {
  409.         AtomAccBuf = 0;
  410.         BondAccBuf = 0;
  411.         printf("%s: Accumulation Buffer turned off - no hw support\n", 
  412.         ProgName);
  413.         return;
  414.     }
  415.     initialized = 1;
  416.     }
  417.     if (AtomAccBuf || BondAccBuf)
  418.     {
  419.     acsize(hwAccbuf);
  420.     } else {
  421.     acsize(0);
  422.     } 
  423.     gconfig();
  424.     Alreadyaccumulated = 0;
  425. }
  426.  
  427. void DoReset()
  428. {
  429.     DoProjection();
  430.     ResetMat(Mat);
  431.     loadmatrix(IdentityMat);
  432.     translate(0.0, 0.0, CenterZ);
  433.     scale(ZoomFactor, ZoomFactor, ZoomFactor);
  434.     RotMode = 0;
  435.     ResetLight();
  436. }
  437.  
  438. static void ResetLight()
  439. {
  440.     LightModel = MODEL_INFINITE;
  441.     SetMaterial(MAT_WHITEPLASTIC);
  442.     SetLight(LIGHT_DEFAULT);
  443.     SetLightModel(MODEL_INFINITE);
  444. }
  445.  
  446. static void DrawBonds()
  447. {
  448.     int bond;
  449.     int bondtype;
  450.     bond_t *bptr;
  451.  
  452. #if 1
  453.     SetLightModel(0);
  454.     if (AAmode != SML_OFF) {
  455.     blendfunction(BF_SA, BF_ONE);
  456.     if (!DispAtoms) {
  457.         zfunction (ZF_ALWAYS);
  458.         /*zbuffer(0);*/
  459.     }
  460.     }
  461. #endif
  462.  
  463.     for (bondtype = 0; bondtype < 8; bondtype++) {
  464.     if (BondTab[bondtype].nbonds > 0) {
  465.         bptr = BondTab[bondtype].bondlist;
  466.         c3f(&(bptr->r));
  467.         for (bond = 0; bond < BondTab[bondtype].nbonds; bond++) { 
  468.         bgnline();
  469.             v3f(&bptr->sx);
  470.             v3f(&bptr->ex);
  471.         endline();
  472.         bptr++;
  473.         }
  474.     }
  475.     }
  476.  
  477. #if 1
  478.     if (AAmode != SML_OFF) {
  479.     blendfunction(BF_ONE, BF_ZERO);
  480.     if (!DispAtoms) {
  481.         zfunction (ZF_LEQUAL);
  482.         /*zbuffer(1);*/
  483.     }
  484.     }
  485.     SetLightModel(LightModel);
  486. #endif
  487. }
  488.  
  489. static void DrawAtoms()
  490. {
  491.     int atomtype;
  492.     atom_t *aptr;
  493.     int atom;
  494.  
  495.     if ((SpherePrim == SPH_LINE) && (BondSmooth != SML_OFF))
  496.     blendfunction(BF_SA,BF_ONE);
  497.  
  498.     if (BitmapSpheres)
  499.     {
  500.     shademodel(FLAT);
  501.     sphbgnbitmap();
  502.     afunction(128,AF_GREATER);
  503.  
  504.     }
  505.     for (atomtype = 0; atomtype < 8; atomtype++) {
  506.     if (AtomTab[atomtype].natoms > 0) {
  507.         SetMatter(atomtype);
  508.         aptr = AtomTab[atomtype].atomlist;
  509.         for (atom = 0; atom < AtomTab[atomtype].natoms; atom++) { 
  510.         if ((aptr->id < 1) || (aptr->id > 7)) {
  511.             printf("drawatom: uknown atom id=%d\n",aptr->id);
  512.         }
  513.         sphdraw(&(aptr->x));
  514.         aptr++;
  515.         }
  516.     }
  517.     }
  518.  
  519.     if (BitmapSpheres)
  520.     {
  521.     sphendbitmap();
  522.     shademodel(GOURAUD);
  523.     afunction(0,AF_ALWAYS);
  524.     }
  525.  
  526.     if ((SpherePrim == SPH_LINE) && (BondSmooth != SML_OFF))
  527.     blendfunction(BF_ONE, BF_ZERO);
  528. }
  529.  
  530. void DisplayAccScene()
  531. {
  532.     float total_weight;
  533.     int i;
  534.  
  535.     if (!ModelRead) return;
  536.     winset(GeomWid);
  537.  
  538.     acbuf(AC_CLEAR, 0.);
  539.     total_weight = 0.;
  540.     for (i = 0; i < Kernel.numsamples; i++) {
  541.     pushmatrix();
  542.     AccWindow(Kernel.samples[i].x, Kernel.samples[i].y, 0.0, 0.0, 1.0);
  543.     if (RollMode && SpinMode)
  544.         sphrotmatrix(SphRotMatrix(Xkernel[i], Xkernel[i], Zkernel[i]));
  545.     else if (RollMode)
  546.         sphrotmatrix(SphRotMatrix(Xkernel[i], Xkernel[i], 0.0));
  547.     else if (SpinMode)
  548.         sphrotmatrix(SphRotMatrix(0.0, 0.0, Zkernel[i]));
  549.     DrawScene();
  550.     acbuf(AC_ACCUMULATE, 1.);
  551.     popmatrix();
  552.  
  553.     if (qtest()) {
  554.         acbuf(AC_RETURN, 1. / (i + 1));
  555.         DrawInfo();
  556.         swapbuffers();
  557.         ClearScreen();
  558.         Alreadyaccumulated = 1;
  559.         return;
  560.     } else if (((i + 1) % 3) == 0) {
  561.         acbuf(AC_RETURN, 1. / (i+1));
  562.         DrawInfo();
  563.         swapbuffers();
  564.     }
  565.     ClearScreen();
  566.     }
  567.     Alreadyaccumulated = 1;
  568. }
  569.  
  570. void DoEventsGeom(long dev, short val)
  571. {
  572.     Matrix tmat;
  573.     winset(GeomWid);
  574.  
  575.     switch(dev) {
  576.  
  577.       case RIGHTMOUSE:
  578.     if (val) {
  579.         if (!GeomLeftDown && !GeomMiddleDown) {
  580.         BuildMainMenu();
  581.         dopup(Menu);
  582.         } else
  583.         GeomRightDown = 1;
  584.     } else {
  585.         GeomRightDown = 0;
  586.         Xpos = getvaluator(MOUSEX) - GeomXorigin;
  587.         Ypos = getvaluator(MOUSEY) - GeomYorigin;
  588.     }
  589.     break;
  590.  
  591.       case LEFTMOUSE:
  592.     if (val) {
  593.         Xpos = getvaluator(MOUSEX) - GeomXorigin;
  594.         Ypos = getvaluator(MOUSEY) - GeomYorigin;
  595.         GeomLeftDown = 1;
  596.     } else {
  597.         GeomLeftDown = 0;
  598.     }
  599.     break;
  600.  
  601.       case MIDDLEMOUSE:
  602.     if (val) {
  603.         Xpos = getvaluator(MOUSEX) - GeomXorigin;
  604.         Ypos = getvaluator(MOUSEY) - GeomYorigin;
  605.         GeomMiddleDown = 1;
  606.     } else
  607.         GeomMiddleDown = 0;
  608.     break;
  609.       case KEYBD:
  610.     switch(val)
  611.     {
  612.       case 'b':
  613.         BitmapSpheres ^= 1;
  614.         fprintf(stderr,"BitmapSpheres = %d\n", BitmapSpheres);
  615.         DoBitmapSpheres();
  616.         DisplayScene();
  617.         break;
  618.       case 'o':
  619.         viewOffset += 0.1;
  620.         DisplayScene();
  621.         break;
  622.       case 'l':
  623.         viewOffset -= 0.1;
  624.         DisplayScene();
  625.         break;
  626. #if 0
  627.       case 'm':
  628.         mmode(MPROJECTION);
  629.         getmatrix(tmat);
  630.         fprintf(stderr,"Projection \n");
  631.         PrintMat(tmat);
  632.         mmode(MVIEWING);
  633.         getmatrix(tmat);
  634.         fprintf(stderr,"Viewing \n");
  635.         PrintMat(tmat);
  636. #endif
  637.     }
  638.       case REDRAW:
  639.     {
  640.     reshapeviewport();
  641.     ConfigureWindow();
  642.     GeomLeftDown = GeomRightDown = GeomMiddleDown = 0;
  643.     ClearScreen();
  644.     swapbuffers();
  645.     ClearScreen();
  646.  
  647.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  648.     !Alreadyaccumulated)
  649.         DisplayAccScene();
  650.     else
  651.         DisplayScene();
  652.     }
  653.     break;
  654.  
  655.       case UPARROWKEY:
  656.     if (!val) break;
  657.     TessUp();
  658.     DisplayScene();
  659.         Alreadyaccumulated = 1;
  660.     break;
  661.  
  662.       case DOWNARROWKEY:
  663.     if (!val) break;
  664.     TessDown();
  665.     DisplayScene();
  666.     Alreadyaccumulated = 1;
  667.     break;
  668.  
  669.       default: break;
  670.     }
  671. }
  672.  
  673. void DoGeom(void)
  674. {
  675.     int moved = 0;
  676.  
  677.     winset(GeomWid);
  678.  
  679.     NewXpos = getvaluator(MOUSEX) - GeomXorigin;
  680.     NewYpos = getvaluator(MOUSEY) - GeomYorigin;
  681.  
  682.     if (GeomLeftDown && GeomMiddleDown && GeomRightDown) {
  683.     moved = 1;
  684.     TranslateXY();
  685.     } else if (GeomLeftDown && GeomMiddleDown && !GeomRightDown) {
  686.     moved = 1;
  687.     Zoom();
  688.     } else if (GeomLeftDown && !GeomMiddleDown && !GeomRightDown) {
  689.     moved = 1;
  690.         if (ABS(NewXpos - Xpos) > AUTO_ROT_TOL)
  691.         Scale();
  692.     } else if (!GeomLeftDown && GeomMiddleDown && !GeomRightDown) {
  693.     moved = 1;
  694.     RotateXY(1);
  695.     } else if (RotMode) {
  696.     moved = 1;
  697.     RotateXY(0);
  698.     }
  699.  
  700.     if (moved) {
  701.     DisplayScene();
  702.     moved = 0;
  703.     } else if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  704.     !Alreadyaccumulated) {
  705.     DisplayAccScene();
  706.     }
  707.  
  708.     Xpos = NewXpos;
  709.     Ypos = NewYpos;
  710.  
  711. }
  712.  
  713. /*
  714.  * SphRotMatrix()
  715.  *    calculates the sphere rotation matrix to send to sphrotmatrix()
  716.  *    to use in SPH_ORIENT mode.
  717.  *    this routine always calcs the rotations as rz*ry*rx = M.
  718.  */
  719.  
  720. static float** SphRotMatrix(float rx, float ry, float rz)
  721. {
  722.     static Matrix mat;
  723.  
  724.     pushmatrix();
  725.     loadmatrix(IdentityMat);
  726.  
  727.     if (rx)    
  728.     rot(rx, 'x');
  729.     if (ry)
  730.     rot(ry, 'y');
  731.     if (rz)
  732.     rot(rz, 'z');
  733.     getmatrix(mat);
  734.     popmatrix();
  735.     return((float **)mat);
  736. }
  737.  
  738. static void RotateXY(int flag)
  739. {
  740.     float rz, rx;
  741.  
  742.     pushmatrix();
  743.     loadmatrix(IdentityMat);
  744.  
  745.     if (flag) {
  746.     if ((NewYpos != Ypos) || (NewXpos != Xpos))
  747.         RotMode = 1;
  748.     else
  749.         RotMode = 0;
  750.  
  751.     My = (float) (NewYpos - Ypos);
  752.     Mx = (float) (NewXpos - Xpos);
  753.     }
  754.  
  755.     rx = 0.0 - My * ANGLE_SHOCK_ABSORBER;
  756.     rz = Mx * ANGLE_SHOCK_ABSORBER;
  757.  
  758.     rot(rx, 'x');
  759.     rot(rz, 'y');
  760.  
  761.     multmatrix(Mat);
  762.     getmatrix(Mat);
  763.  
  764.     popmatrix();
  765.  
  766.     Xpos = NewXpos;
  767.     Ypos = NewYpos;
  768. }
  769.  
  770. static void Zoom()
  771. {
  772.     float mx;
  773.  
  774.     mx = (float) (NewXpos - Xpos);
  775.     TransZ += - mx * COORD_SHOCK_ABSORBER;
  776.     Xpos = NewXpos;
  777. }
  778.  
  779. static void TranslateXY()
  780. {
  781.     float mx, my;
  782.  
  783.     mx = (float) (NewXpos - Xpos);
  784.     my = (float) (NewYpos - Ypos);
  785.     TransX += mx * COORD_SHOCK_ABSORBER; 
  786.     TransY += my * COORD_SHOCK_ABSORBER;
  787.     Xpos = NewXpos;
  788.     Ypos = NewYpos;
  789. }
  790.  
  791. static void Scale()
  792. {
  793.     float mx;
  794.     float factor;
  795.  
  796.     mx = (float) (NewXpos - Xpos);
  797.     ScaleFactor *=  (1.0 + mx * ZoomFactor / (float) GeomXsize);
  798. }
  799.  
  800. void DoExitGeom()
  801. {
  802.     if (Menu != -1)
  803.     freepup(Menu);
  804. }
  805.  
  806. static void SetMatter(int m)
  807. {
  808.     register int i = m - 1;
  809.  
  810.     if (BitmapSpheres)
  811.     sphcolor(atom_colors[i]);
  812.     else 
  813.     ChangeMaterial(atom_props[i]);
  814. }
  815.  
  816. static void TessDown()
  817. {
  818.     if (SphereDepth > 1) SphereDepth--;
  819.     printf("depth down to %d \n", SphereDepth);
  820.     sphmode(SPH_DEPTH, SphereDepth);
  821.     CalcInfo();
  822. }
  823.  
  824. static void TessUp()
  825. {
  826.     if (SphereDepth < SPH_MAXDEPTH) SphereDepth++;
  827.     printf("depth up to %d \n", SphereDepth);
  828.     sphmode(SPH_DEPTH, SphereDepth);
  829.     CalcInfo();
  830. }
  831. static void ResetMat(Matrix m)
  832. {
  833.     m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0;
  834.     m[0][1] = m[0][2] = m[0][3] = 0.0;
  835.     m[1][0] = m[1][2] = m[1][3] = 0.0;
  836.     m[2][0] = m[2][1] = m[2][3] = 0.0;
  837.     m[3][0] = m[3][1] = m[3][2] = 0.0;
  838. }
  839.  
  840. static void PrintMat(Matrix mat)
  841. {
  842.     int i;
  843.  
  844.     printf("matrix:\n");
  845.     for (i = 0; i < 4; i++) 
  846.     printf("\t%5.5f %5.5f %5.5f %5.5f\n",
  847.         mat[i][0], mat[i][1], mat[i][2], mat[i][3]);
  848.     printf("\n");
  849. }
  850.  
  851. void DoLineSmooth()
  852. {
  853.     winset(GeomWid);
  854.     if (FastDraw) {
  855.     BondSmooth = SML_OFF;
  856.     BondEndCorrect = SML_OFF;
  857.     }
  858.  
  859.     AAmode = BondSmooth | BondEndCorrect;
  860.     linesmooth(AAmode);
  861. }
  862.  
  863. void DoBitmapSpheres(void)
  864. {
  865.     if (!hwBitmapSpheres)
  866.     return;
  867.     winset(GeomWid);
  868.     if (BitmapSpheres)
  869.     {
  870.     if (Multisample)
  871.     {
  872.         Multisample = 0;
  873.         DoMultisample();
  874.     }
  875.     RGBsize(12);
  876.     if (AtomAccBuf)
  877.     {
  878.         AtomAccBuf = 0;
  879.     }
  880.     if (BondAccBuf)
  881.     {
  882.         BondAccBuf = 0;
  883.     }
  884.     acsize(0);
  885.     gconfig();
  886.     }
  887.     CalcInfo();
  888.     DrawPanel();
  889. }
  890.  
  891. void DoMultisample(void)
  892. {
  893.     if (!hwMultisample)
  894.     return;
  895.     winset(GeomWid);
  896.     if (Multisample) 
  897.     {
  898.     stensize(0);
  899.     acsize(0);
  900.     zbsize(0);
  901.     mssize(8, 24, 1);
  902.     multisample(1);
  903.     gconfig();
  904.     } else
  905.     {
  906.     mssize(0, 0, 0);
  907.     multisample(0);
  908.     zbsize(32);
  909.     gconfig();
  910.     }
  911. }
  912.  
  913. void DoStereo(void)
  914. {
  915.     long bits;
  916.     if (!hwStereo)
  917.     return;
  918.     winset(GeomWid);
  919.  
  920.     if (Stereo) 
  921.     {
  922.     /* set to 8 bits color so can allocate stereo buffers 
  923.      * when have small pixel depth
  924.      * Note: this is incompatible with hw accumulation buffer !!!
  925.      * Note: bitmap spheres require RGBsize(12) !!!
  926.      */
  927.     if (!BitmapSpheres)
  928.         RGBsize(8);
  929.     acsize(0);
  930.     stereobuffer();
  931.     doublebuffer();
  932.     gconfig();
  933.     } else
  934.     {
  935.     RGBsize(12);
  936.     monobuffer();
  937.     doublebuffer();
  938.     gconfig();
  939.     DoProjection();
  940.     }
  941. }
  942.  
  943. void DoProjection()
  944. {
  945.     winset(GeomWid);
  946.     mmode(MPROJECTION);
  947.     if (!Perspective)
  948.     {
  949.     if (Stereo)
  950.     {
  951.         float offset = projOffset * .1;
  952.         ortho(Left + offset, Right + offset, Bottom, Top, Near, Far);    
  953.     }
  954.     else
  955.         ortho(Left, Right, Bottom, Top, Near, Far);    
  956.     } else 
  957.     {
  958.     if (Stereo)
  959.         stereopersp(FOVY, GeomAspect, Near, Far, 
  960.             DISTANCE_TO_SCREEN, projOffset);
  961.     else
  962.         perspective(FOVY, GeomAspect, Near, Far);
  963.     }
  964.     mmode(MVIEWING);
  965. }
  966.  
  967. static void stereopersp(int fovy, float aspect,
  968.         float near, float far, float conv, float eye)
  969. {
  970.     float left, right, top, bottom;
  971.     float gltan;
  972.     float offset=0.;
  973.  
  974.     gltan = ftan(fovy/2.0/10.0*M_PI/180.0);
  975.  
  976.     top = gltan * near;
  977.     bottom = -top;
  978.  
  979.     gltan = ftan(fovy*aspect/2.0/10.0*M_PI/180.0);
  980.     left = -gltan*near + eye/conv*near;
  981.     right = gltan*near + eye/conv*near;
  982.  
  983.     window(left, right, bottom, top, near, far);
  984.  
  985.     translate(eye, 0.0, 0.0);
  986.  
  987. }
  988.  
  989. /*
  990.  * Shift around window for accumulation buffer sampling
  991.  */
  992. static void AccWindow(float pixdx, float pixdy, float eyedx, float eyedy, 
  993.             float focus)
  994. {
  995.     float hsize, vsize; 
  996.     float dx, dy;
  997.  
  998.     if(focus<0.0)
  999.     focus = -focus;
  1000.  
  1001.     if (!Perspective)
  1002.     {
  1003.     hsize = Right-Left;
  1004.     vsize = Top-Bottom;
  1005.     dx = -(pixdx*hsize/GeomXsize+eyedx*Near/focus);
  1006.     dy = -(pixdy*vsize/GeomYsize+eyedy*Near/focus);
  1007.  
  1008.     ortho(Left+dx,Right+dx,Bottom+dy,Top+dy,Near,Far);
  1009.     }
  1010.     else
  1011.     {
  1012.     float left, right, top, bottom;
  1013.     float gltan;
  1014.  
  1015.     gltan = ftan(FOVY/2.0/10.0*M_PI/180.0);
  1016.  
  1017.     top = gltan * Near; 
  1018.     bottom = -top;
  1019.     gltan = ftan(FOVY*GeomAspect/2.0/10.0*M_PI/180.0);
  1020.     left = -gltan*Near;
  1021.     right = gltan*Near;
  1022.  
  1023.     hsize = right-left;
  1024.     vsize = top-bottom;
  1025.  
  1026.     dx = -(pixdx*hsize/GeomXsize+eyedx*Near/focus);
  1027.     dy = -(pixdy*vsize/GeomYsize+eyedy*Near/focus);
  1028.     window(left+dx,right+dx,bottom+dy,top+dy,Near,Far);
  1029.     }
  1030.     translate(-eyedx,-eyedy,0.0);
  1031. }
  1032.  
  1033.  
  1034. void DoDispAtoms(void)
  1035. {
  1036.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  1037.         !Alreadyaccumulated)
  1038.     DisplayAccScene();
  1039.     else 
  1040.     DisplayScene();
  1041. }
  1042.  
  1043.  
  1044. void DoDispBonds(void)
  1045. {
  1046.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  1047.     !Alreadyaccumulated)
  1048.     DisplayAccScene();
  1049.     else 
  1050.     DisplayScene();
  1051. }
  1052.  
  1053. void DoFastDraw(void)
  1054. {
  1055.     BondSmooth = SML_OFF;
  1056.     BondEndCorrect = SML_OFF;
  1057.     DoLineSmooth();
  1058.     BondAccBuf = 0;
  1059.     AtomAccBuf = 0;
  1060.  
  1061.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  1062.     !Alreadyaccumulated)
  1063.     DisplayAccScene();
  1064.     else 
  1065.     DisplayScene();
  1066. }
  1067.  
  1068.  
  1069. void DoSpinMode(void)
  1070. {
  1071.     if (SpinMode && !Orient)
  1072.     {
  1073.     Orient = 1;
  1074.     DoOrient();
  1075.     }
  1076.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  1077.     !Alreadyaccumulated)
  1078.     DisplayAccScene();
  1079.     else 
  1080.     DisplayScene();
  1081. }
  1082.  
  1083. void DoAccRollMode(void)
  1084. {
  1085.     if (RollMode && !Orient)
  1086.     {
  1087.     Orient = 1;
  1088.     DoOrient();
  1089.     }
  1090.  
  1091.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  1092.     !Alreadyaccumulated)
  1093.     DisplayAccScene();
  1094.     else DisplayScene();
  1095. }
  1096.  
  1097. void DoHemi(void)
  1098. {
  1099.     if (!Orient || (Orient && !Hemi)) SetBackface(1);
  1100.     sphmode(SPH_HEMI, Hemi);
  1101.     CalcInfo();
  1102.     DisplayScene();
  1103. }
  1104.  
  1105. void DoOrient(void)
  1106. {
  1107.     sphmode(SPH_ORIENT, Orient);
  1108.     CalcInfo();
  1109.     if (!Orient || (Orient && !Hemi)) SetBackface(1);
  1110.     else SetBackface(0);
  1111.     DisplayScene();
  1112. }
  1113.  
  1114. void DefineLight(void)
  1115. {
  1116.     DefineMaterials();
  1117.     DefineLights();
  1118.     DefineLightModels();
  1119. }
  1120.  
  1121. void CalcInfo(void)
  1122. {
  1123.     NumPolysAtom = sphgnpolys();
  1124.     NumPolys = NumPolysAtom * Natoms;
  1125. }
  1126.  
  1127. static void DrawInfo(void)
  1128. {
  1129.     char str[100];
  1130.  
  1131. #ifdef USEOVERLAY
  1132.     drawmode(OVERDRAW);
  1133.     color(WHITE);
  1134. #else
  1135.     zfunction(ZF_ALWAYS);
  1136.     cpack(0xffffff);
  1137. #endif /* USEOVERLAY */
  1138.  
  1139.     SetLightModel(0);
  1140.     ortho2(-0.5, GeomXsize - 0.5, -0.5, GeomYsize - 0.5);
  1141.     pushmatrix();
  1142.     loadmatrix(IdentityMat);
  1143.  
  1144.     if (DispAtoms) {
  1145.  
  1146.     cmov2i(20, 20);
  1147.     sprintf(str, "Atoms: %d", Natoms);
  1148.     charstr(str);
  1149.  
  1150.     if (!BitmapSpheres)
  1151.     {
  1152.         cmov2i(20, 35);
  1153.         sprintf(str, "Polygons per Atom: %d", NumPolysAtom);
  1154.         charstr(str);
  1155.  
  1156.         cmov2i(20, 50);
  1157.         sprintf(str, "Total number of Polygons: %d", NumPolys);
  1158.         charstr(str);
  1159.     }
  1160.     }
  1161.     if (DispBonds) {
  1162.     cmov2i(20, 65);
  1163.     sprintf(str, "Bonds: %d", Nbonds);
  1164.     charstr(str);
  1165.     }
  1166.  
  1167.     SetLightModel(LightModel);
  1168.     popmatrix();
  1169.     if (!Stereo)
  1170.     DoProjection();
  1171.  
  1172. #ifdef USEOVERLAY
  1173.     drawmode(NORMALDRAW);
  1174. #else
  1175.     zfunction(ZF_LEQUAL);
  1176. #endif /* USEOVERLAY */
  1177. }
  1178.  
  1179. static void DrawScene(void)
  1180. {
  1181.     if (Depthcue)
  1182.     fogvertex(FG_ON, NULL);
  1183.  
  1184.     pushmatrix();
  1185.     
  1186.     translate(TransX, TransY, TransZ);
  1187.     scale(ScaleFactor, ScaleFactor, ScaleFactor);
  1188.  
  1189.     multmatrix(Mat);
  1190.     translate(-centerx, -centery, -centerz);
  1191.  
  1192.     if (DispAtoms)
  1193.     DrawAtoms();
  1194.  
  1195.     if (DispBonds)
  1196.     DrawBonds();
  1197.  
  1198.     popmatrix();
  1199.     
  1200.     if (Depthcue)
  1201.     fogvertex(FG_OFF, NULL);
  1202. }
  1203.  
  1204. void DisplayScene(void)
  1205. {
  1206.     if (!ModelRead) 
  1207.     return;
  1208.     winset(GeomWid);
  1209.     
  1210.     if (Stereo)
  1211.     {
  1212.     leftbuffer(1);
  1213.     rightbuffer(0);
  1214.     projOffset = viewOffset;
  1215.     DoProjection();
  1216.     }
  1217.     ClearScreen();
  1218.     DrawScene();
  1219.     DrawInfo();
  1220.     if (Stereo)
  1221.     {
  1222.     leftbuffer(0);
  1223.     rightbuffer(1);
  1224.     projOffset = -viewOffset;
  1225.     DoProjection();
  1226.     ClearScreen();
  1227.     DrawScene();
  1228.     DrawInfo();
  1229.     }
  1230.     swapbuffers();
  1231.     Alreadyaccumulated = 0;
  1232. }
  1233.  
  1234. void ChangeRadius(void)
  1235. {
  1236.     int atomtype;
  1237.     atom_t *aptr;
  1238.     int atom;
  1239.  
  1240.     for (atomtype = 0; atomtype < 8; atomtype++) {
  1241.     if (AtomTab[atomtype].natoms > 0) {
  1242.         aptr = AtomTab[atomtype].atomlist;
  1243.         for (atom = 0; atom < AtomTab[atomtype].natoms; atom++) { 
  1244.         if ((aptr->id < 1) || (aptr->id > 7)) {
  1245.             printf("drawatom: uknown atom id=%d\n",aptr->id);
  1246.         }
  1247.         aptr->rad = aptr->org_rad * RadScaleFactor;
  1248.         aptr++;
  1249.         }
  1250.     }
  1251.     } 
  1252.     DisplayScene();   
  1253. }
  1254.  
  1255. void SetGeomTitle(void)
  1256. {
  1257.     if (ModelId == -1) return;
  1258.     winset(GeomWid);
  1259.     wintitle(Models[ModelId].name);
  1260. }
  1261.  
  1262. void SetBackface(flag)
  1263.     int flag;
  1264. {
  1265.     winset(GeomWid);
  1266.     backface(flag);
  1267. }
  1268.  
  1269. int ReadKernel(char *filename)
  1270. {
  1271.     FILE *fpt = 0;
  1272.     int i;
  1273.     float x, y;
  1274.  
  1275.     if (!(fpt = fopen(filename, "r"))) {
  1276.     fprintf(stderr, "%s: cannot read kernel from file %s\n", ProgName, 
  1277.         filename);
  1278.     return -1;
  1279.     }
  1280.  
  1281.     (void) fscanf(fpt, "%d", &Kernel.numsamples);
  1282.     for (i = 0; i < Kernel.numsamples; i++) {
  1283.     fscanf(fpt, "%f %f", &x, &y);
  1284.     Kernel.samples[i].x = x;
  1285.     Kernel.samples[i].y = y;
  1286.     Kernel.samples[i].weight = 1. - sqrt(x*x + y*y);
  1287.     }
  1288.     return 0;
  1289. }
  1290.  
  1291. #if 0
  1292. /* libsphere bitmap stubs */
  1293.  
  1294. void sphbgnbitmap(void) { }
  1295. void sphendbitmap(void) { }
  1296. void sphcolor(float clr[4]) {}
  1297.  
  1298. #endif
  1299.  
  1300. #if 0
  1301. /*
  1302.  * fast RE sphere stubs
  1303.  */
  1304. #endif
  1305.